package com.yami.shop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.bean.model.*;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ResponseEnum;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.common.util.StringUtils;
import com.yami.shop.dto.group.UserGroupDTO;
import com.yami.shop.dto.group.UserGroupIdDTO;
import com.yami.shop.security.common.bo.UserInfoInTokenBO;
import com.yami.shop.security.common.util.AuthUserContext;
import com.yami.shop.service.*;
import io.rong.RongCloud;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.yami.shop.common.response.ServerResponseEntity.success;

@Service
@Slf4j
public class RongYunUsergroupServiceImpl {

    @Autowired
    private RongCloud rongCloud;

    @PostConstruct
    public void init() {}

    @Autowired
    private MeltCloudUsergroupService usergroupService;

    @Autowired
    private MeltCloudGroupService groupService;

    @Autowired
    private MeltCloudGroupUserService groupUserService;
    
    @Autowired
    private MeltCloudUsergroupUserService usergroupUserService;
    
    @Autowired
    private ApiUtilServiceImpl apiUtilService;
    
    @Autowired
    private MeltCloudChannelUserGroupService channelUserGroupService;
    
    @Autowired
    private MeltCloudUserService userService;
    
    @Autowired
    private MeltCloudChannelService channelService;
    
    
    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity create(UserGroupDTO param) throws Exception {
        List<String> names = param.getNames();
        Long groupId = param.getGroupId();
        String currentUserId = operationPermissionVerify(groupId, true, null);
        ultraGroupExpireCheck(groupId, currentUserId, null);
        if (CollUtil.isEmpty(names) || names.size() > 10) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "用户组不能为空或超过10个");
        }
        MeltCloudGroup group = groupService.getById(groupId);
        if (group.getType().equals("0")) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "只有超级群可以创建用户组！");
        }
        long count = usergroupService.count(Wrappers.lambdaQuery(MeltCloudUsergroup.class).eq(MeltCloudUsergroup::getGroupId, groupId).eq(MeltCloudUsergroup::getStatus, 0));
        if (count + names.size() > 50) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "超级群中最多创建50个用户组，已存在" + count + "个！");
        }
        Set<String> nameSet = names.stream().collect(Collectors.toSet());
        if (nameSet.size() != names.size()) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "用户组名称不能重复！");
        }
        List<MeltCloudUsergroup> userGroups = new ArrayList<>();
        for (String name : names) {
            if (StringUtils.isEmpty(name)) {
                throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "用户组名称不能为空！");
            }
            MeltCloudUsergroup one = usergroupService.getOne(Wrappers.lambdaQuery(MeltCloudUsergroup.class).eq(MeltCloudUsergroup::getGroupId, groupId).eq(MeltCloudUsergroup::getName, name).eq(MeltCloudUsergroup::getStatus, 0));
            if (one != null) {
                throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "用户组名称："+ name +"已存在！");
            }
            MeltCloudUsergroup userGroup = MeltCloudUsergroup.builder().groupId(groupId).name(name).creatorUserId(currentUserId).build();
            userGroups.add(userGroup);
        }
        usergroupService.saveBatch(userGroups);
        List<UserGroupIdDTO> userGroupIdDTOS = BeanUtil.copyToList(userGroups, UserGroupIdDTO.class);
        UserGroupIdDTO[] userGroupArr = userGroupIdDTOS.stream().toArray(UserGroupIdDTO[]::new);
        Map<String, Object> map = new HashMap<>();
        map.put("groupId", groupId);
        map.put("userGroups", userGroupArr);
        JSONObject jsonObject = apiUtilService.requestPost("/ultragroup/usergroup/add.json", "application/json", map);
        if (!jsonObject.getInteger("code").equals(200)) {
            log.error("请求失败！");
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "创建用户组失败！");
        }
        return success(jsonObject);
    }


    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity delete(UserGroupDTO param) throws Exception {
        Long groupId = param.getGroupId();
        Long userGroupId = param.getUserGroupId();
        if (Objects.isNull(groupId) || Objects.isNull(userGroupId)) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "超级群聊或用户组为空！");
        }
        String currentUserId = operationPermissionVerify(groupId, true, userGroupId);
        ultraGroupExpireCheck(groupId, currentUserId, userGroupId);
        usergroupService.update(Wrappers.lambdaUpdate(MeltCloudUsergroup.class)
                .set(MeltCloudUsergroup::getStatus, 1)
                .eq(MeltCloudUsergroup::getGroupId, groupId).eq(MeltCloudUsergroup::getUserGroupId, userGroupId));
        // 删除用户组成员
        usergroupUserService.update(Wrappers.lambdaUpdate(MeltCloudUsergroupUser.class)
                .set(MeltCloudUsergroupUser::getIsDel, 1)
                .eq(MeltCloudUsergroupUser::getGroupId, groupId).eq(MeltCloudUsergroupUser::getUserGroupId, userGroupId));
        // 删除用户组与频道的绑定关系
        channelUserGroupService.remove(Wrappers.lambdaQuery(MeltCloudChannelUserGroup.class)
                .eq(MeltCloudChannelUserGroup::getGroupId, groupId).eq(MeltCloudChannelUserGroup::getUserGroupId, userGroupId));
        Map<String, Object> map = new HashMap<>();
        map.put("groupId", groupId);
        map.put("userGroupIds", userGroupId);
        JSONObject jsonObject = apiUtilService.requestPost("/ultragroup/usergroup/del.json", map);
        if (!jsonObject.getInteger("code").equals(200)) {
            log.error("请求失败！");
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "删除用户组失败！");
        }
        return success();
    }


    /**
     * 查询用户组列表
     * @param groupId
     * @return
     * @throws Exception
     */
    public ServerResponseEntity<List<MeltCloudUsergroup>> getByGroupId(Long groupId) throws Exception {
        List<MeltCloudUsergroup> list = usergroupService.list(Wrappers.lambdaQuery(MeltCloudUsergroup.class).eq(MeltCloudUsergroup::getGroupId, groupId).eq(MeltCloudUsergroup::getStatus, 0));
        Map<String, Object> map = new HashMap<>();
        map.put("groupId", groupId);
        JSONObject jsonObject = apiUtilService.requestPost("/ultragroup/usergroup/query.json", map);
        if (!jsonObject.getInteger("code").equals(200)) {
            log.error("请求失败！");
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "查询用户组失败！");
        }
        return success(list);
        
    }

    /**
     * 用户组添加用户
     * @param param
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity addUser(UserGroupDTO param) throws Exception{
        Long groupId = param.getGroupId();
        Long userGroupId = param.getUserGroupId();
        List<String> userIds = param.getUserIds().stream().distinct().collect(Collectors.toList());
        if (groupId == null || userGroupId == null) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "超级群和用户组信息不能为空！");
        }
        String currentUserId = operationPermissionVerify(groupId, false, null);
        ultraGroupExpireCheck(groupId, currentUserId, userGroupId);
        if (CollUtil.isEmpty(userIds) || userIds.size() > 20)
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "用户不能为空或超过20个！");
        MeltCloudGroup group = groupService.getById(groupId);
        if (group.getIsDismiss().equals("1")) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "该超级群已解散！");
        }
        MeltCloudUsergroup userGroup = usergroupService.getById(userGroupId);
        if (userGroup == null)
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "用户组不存在！");
        if (userGroup.getStatus() == 1)
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "用户组已删除！");
        LambdaQueryWrapper<MeltCloudUsergroupUser> wp = Wrappers.lambdaQuery(MeltCloudUsergroupUser.class)
                .eq(MeltCloudUsergroupUser::getGroupId, groupId).eq(MeltCloudUsergroupUser::getUserGroupId, userGroupId).eq(MeltCloudUsergroupUser::getIsDel, 0);
        long count = usergroupUserService.count(wp);
        if (count + userIds.size() > 100) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "最多由100位组成，已有" + count + "位");
        }
        LambdaQueryWrapper<MeltCloudUsergroupUser> wrapper = Wrappers.lambdaQuery(MeltCloudUsergroupUser.class).eq(MeltCloudUsergroupUser::getGroupId, groupId).eq(MeltCloudUsergroupUser::getUserGroupId, userGroupId).in(MeltCloudUsergroupUser::getUserId, userIds);
        List<MeltCloudUsergroupUser> existList = usergroupUserService.list(wrapper);
        Map<String, MeltCloudUsergroupUser> existMap = existList.stream().collect(Collectors.toMap(MeltCloudUsergroupUser::getUserId, Function.identity()));
        List<MeltCloudUsergroupUser> list = new ArrayList<>();
        for (String userId : userIds) {
            MeltCloudUsergroupUser existUser = existMap.get(userId);
            if (existUser == null) {
                MeltCloudUsergroupUser usergroupUser = MeltCloudUsergroupUser.builder()
                        .groupId(groupId).userGroupId(userGroupId).userId(userId).createTime(new Date()).build();
                list.add(usergroupUser);
            } else {
                if (existUser.getIsDel() == 1) {
                    existUser.setIsDel(0);
                    list.add(existUser);
                } else {
                    MeltCloudUser user = userService.getById(userId);
                    throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, user.getUserName() + "已在当前用户组中！");
                }
            }
        }
        usergroupUserService.saveOrUpdateBatch(list);
        String userIdStr = userIds.stream().collect(Collectors.joining(","));
        Map<String, Object> map = new HashMap<>();
        map.put("groupId", groupId);
        map.put("userGroupId", userGroupId);
        map.put("userIds", userIdStr);
        JSONObject jsonObject = apiUtilService.requestPost("/ultragroup/usergroup/user/add.json", map);
        if (!jsonObject.getInteger("code").equals(200)) {
            log.error("请求失败！");
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "用户组添加用户失败！");
        }
        return success();
    }

    /**
     * 删除用户组成员
     * @param param
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity delUser(UserGroupDTO param) throws Exception{
        Long groupId = param.getGroupId();
        Long userGroupId = param.getUserGroupId();
        if (groupId == null || userGroupId == null) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "超级群和用户组信息不能为空！");
        }
        List<String> userIds = param.getUserIds().stream().distinct().collect(Collectors.toList());
        if (CollUtil.isEmpty(userIds) || userIds.size() > 20)
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "用户不能为空或超过20个！");
        String currentUserId = operationPermissionVerify(groupId, true, userGroupId);
        ultraGroupExpireCheck(groupId, currentUserId, userGroupId);
        LambdaQueryWrapper<MeltCloudUsergroupUser> wrapper = Wrappers.lambdaQuery(MeltCloudUsergroupUser.class).eq(MeltCloudUsergroupUser::getGroupId, groupId).eq(MeltCloudUsergroupUser::getUserGroupId, userGroupId).in(MeltCloudUsergroupUser::getUserId, userIds);
        List<MeltCloudUsergroupUser> existList = usergroupUserService.list(wrapper);
        existList.forEach(ugu -> ugu.setIsDel(1));
        usergroupUserService.updateBatchById(existList);
        String userIdStr = userIds.stream().collect(Collectors.joining(","));
        Map<String, Object> map = new HashMap<>();
        map.put("groupId", groupId);
        map.put("userGroupId", userGroupId);
        map.put("userIds", userIdStr);
        JSONObject jsonObject = apiUtilService.requestPost("/ultragroup/usergroup/user/del.json", map);
        if (!jsonObject.getInteger("code").equals(200)) {
            log.error("请求失败！");
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "用户组移出用户失败！");
        }
        return success();
    }


    /**
     * 查用户所在的用户组
     * @param groupId
     * @param userId
     * @return
     * @throws Exception
     */
    public ServerResponseEntity getByUserId(Long groupId, String userId) throws Exception {
        List<MeltCloudUsergroup> list = usergroupService.getByUserId(groupId, userId);
        Map<String, Object> map = new HashMap<>();
        map.put("groupId", groupId);
        map.put("userId", userId);
        map.put("page", 1);
        map.put("pageSize", 50);
        JSONObject jsonObject = apiUtilService.requestPost("/ultragroup/user/usergroup/query.json", map);
        if (!jsonObject.getInteger("code").equals(200)) {
            log.error("请求失败！");
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "查询用户组失败！");
        }
        return success(list);
    }

    /**
     * 用户组绑定频道
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity bind(UserGroupDTO param) throws Exception {
        Long groupId = param.getGroupId();
        String channelId = param.getChannelId();
        List<Long> userGroupIds = param.getUserGroupIds().stream().distinct().collect(Collectors.toList());
        if (groupId == null || StringUtils.isEmpty(channelId)) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "超级群和频道信息不能为空！");
        }
        if (CollUtil.isEmpty(userGroupIds) || userGroupIds.size() > 10)
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "用户组不能为空或超过10个！");
        String currentUserId = operationPermissionVerify(groupId, true, null);
        ultraGroupExpireCheck(groupId, currentUserId, null);
        MeltCloudGroup group = groupService.getById(groupId);
        if (group.getType().equals("0")) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "只有超级群可以绑定用户组！");
        }
        if (channelId.equals("RCDefault"))
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "用户组不能绑定默认频道！");
        MeltCloudChannel channel = channelService.getOne(Wrappers.lambdaQuery(MeltCloudChannel.class).eq(MeltCloudChannel::getGroupId, groupId).eq(MeltCloudChannel::getChannelId, channelId).eq(MeltCloudChannel::getChannelStatus, 0));
        if (channel == null)
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "该频道不存在！");
        long count = channelUserGroupService.count(Wrappers.lambdaQuery(MeltCloudChannelUserGroup.class).eq(MeltCloudChannelUserGroup::getGroupId, groupId).eq(MeltCloudChannelUserGroup::getChannelId, channelId));
        if (count + userGroupIds.size() > 10) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "每个频道最多绑定10个用户组，已存在" + count + "个！");
        }

        List<MeltCloudChannelUserGroup> list = new ArrayList<>();
        for (Long userGroupId : userGroupIds) {
            MeltCloudUsergroup userGroup = usergroupService.getById(userGroupId);
            if (userGroup == null)
                throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "用户组不存在！");
            if (userGroup.getStatus() == 1)
                throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "用户组已删除！");
            MeltCloudChannelUserGroup channelUserGroup = MeltCloudChannelUserGroup.builder().groupId(groupId).channelId(channelId).userGroupId(userGroupId).build();
            list.add(channelUserGroup);
        }
        channelUserGroupService.saveBatch(list);
        String userGroupStr = userGroupIds.stream().map(aLong -> aLong.toString()).collect(Collectors.joining(","));
        Map<String, Object> map = new HashMap<>();
        map.put("groupId", groupId);
        map.put("busChannel", channelId);
        map.put("userGroupIds", userGroupStr);
        JSONObject jsonObject = apiUtilService.requestPost("/ultragroup/channel/usergroup/bind.json", map);
        if (!jsonObject.getInteger("code").equals(200)) {
            log.error("请求失败！");
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "绑定用户组失败！");
        }
        return success(jsonObject);

    }

    /**
     * 解绑频道
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity unbind(UserGroupDTO param) throws Exception {
        Long groupId = param.getGroupId();
        String channelId = param.getChannelId();
        List<Long> userGroupIds = param.getUserGroupIds().stream().distinct().collect(Collectors.toList());
        if (CollUtil.isEmpty(userGroupIds) || userGroupIds.size() > 10)
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "用户组不能为空或超过10个！");
        String currentUserId = operationPermissionVerify(groupId, true, null);
        ultraGroupExpireCheck(groupId, currentUserId, null);
        channelUserGroupService.remove(Wrappers.lambdaQuery(MeltCloudChannelUserGroup.class)
                .eq(MeltCloudChannelUserGroup::getGroupId, groupId).eq(MeltCloudChannelUserGroup::getChannelId, channelId).in(MeltCloudChannelUserGroup::getUserGroupId, userGroupIds));
        String userGroupStr = userGroupIds.stream().map(aLong -> aLong.toString()).collect(Collectors.joining(","));
        Map<String, Object> map = new HashMap<>();
        map.put("groupId", groupId);
        map.put("busChannel", channelId);
        map.put("userGroupIds", userGroupStr);
        JSONObject jsonObject = apiUtilService.requestPost("/ultragroup/channel/usergroup/unbind.json", map);
        if (!jsonObject.getInteger("code").equals(200)) {
            log.error("请求失败！");
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "解绑用户组失败！");
        }
        return success(jsonObject);
    }

    /**
     * 查询频道绑定的用户组
     * @param groupId
     * @param channelId
     * @return
     * @throws Exception
     */
    public ServerResponseEntity queryUserGroup(Long groupId, String channelId) {
        List<MeltCloudUsergroup> list = usergroupService.getByChannelId(groupId, channelId);
        return success(list);
    }

    /**
     * 查询用户组绑定的频道
     * @param groupId
     * @param userGroupId
     * @return
     * @throws Exception
     */
    public ServerResponseEntity queryChannel(Long groupId, Long userGroupId) {
        List<MeltCloudChannel> list = channelService.getByUserGroupId(groupId, userGroupId);
        return success(list);
    }


    private String operationPermissionVerify(Long groupId, boolean isManger, Long userGroupId) {
        String currentUserId = "";
        UserInfoInTokenBO userTokenBO = AuthUserContext.get();
        if (userTokenBO.getSysType().equals(1)) {
            currentUserId = "shop_" + userTokenBO.getUserId();
        } else if (userTokenBO.getSysType().equals(2)) {
            currentUserId = "plat_" + userTokenBO.getUserId();
        } else if (userTokenBO.getSysType().equals(0)) {
            currentUserId = userTokenBO.getUserId();
        }
        if (isManger) {
            MeltCloudGroup group = groupService.getById(groupId);
            if (group == null || group.getIsDismiss().equals("1")) {
                throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "该群不存在或已解散！");
            }
            if (!group.getCreatorUserId().equals(currentUserId)) {
                MeltCloudGroupUser groupUser = groupUserService.getOne(Wrappers.lambdaQuery(MeltCloudGroupUser.class)
                        .eq(MeltCloudGroupUser::getGroupId, groupId).eq(MeltCloudGroupUser::getUserId, currentUserId).eq(MeltCloudGroupUser::getIsManage, 1));
                if (Objects.isNull(groupUser)) {
                    if (Objects.isNull(userGroupId)) {
                        throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "您非群主或管理员不能操作！");
                    } else {
                        MeltCloudUsergroup userGroup = getUserGroup(groupId, userGroupId);
                        if (!userGroup.getCreatorUserId().equals(currentUserId)) {
                            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "您非群主管理员或用户组创建者不能操作！");
                        }
                    }
                }
            }
        }
        return currentUserId;
    }
    

    /**
     * 检查超级群到期操作权限
     * @param groupId 群id
     * @param currentUserId 当前人id
     * @return
     */
    private void ultraGroupExpireCheck(Long groupId, String currentUserId, Long userGroupId) {
        MeltCloudGroup group = groupService.getById(groupId);
        if (group.getType().equals("1") && group.getIsArrears() == 1) {
            if (StringUtils.isEmpty(currentUserId)) {
                throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "操作人不能为空！");
            }
            if (group.getCreatorUserId().equals(currentUserId)) {
                throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "该群已欠费，不能操作！");
            } else {
                MeltCloudGroupUser groupUser = groupUserService.getOne(Wrappers.lambdaQuery(MeltCloudGroupUser.class)
                        .eq(MeltCloudGroupUser::getGroupId, groupId).eq(MeltCloudGroupUser::getUserId, currentUserId).eq(MeltCloudGroupUser::getIsManage, 1));
                if (Objects.nonNull(groupUser)) {
                    throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "该群已欠费，不能操作！");
                } else {
                    if (Objects.nonNull(userGroupId)) {
                        MeltCloudUsergroup userGroup = getUserGroup(groupId, userGroupId);
                        if (userGroup.getCreatorUserId().equals(currentUserId)) {
                            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "该群已欠费，不能操作！");
                        }
                    }
                }
            }
        }
    }

    private MeltCloudUsergroup getUserGroup(Long groupId, Long userGroupId) {
        MeltCloudUsergroup one = usergroupService.getOne(Wrappers.lambdaQuery(MeltCloudUsergroup.class).eq(MeltCloudUsergroup::getUserGroupId, userGroupId).eq(MeltCloudUsergroup::getGroupId, groupId).eq(MeltCloudUsergroup::getStatus, 0));
        if (Objects.isNull(one)) {
            throw new YamiShopBindException(ResponseEnum.SHOW_FAIL, "该用户组不存在！");
        }
        return one;
    }
    

}
